<!DOCTYPE html>
<html ng-app="strapDemoApp">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Angular-Strap 组件演示 - ng-components-ui</title>
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/bootstrap@3.4.1/dist/css/bootstrap.min.css"
    />
    <link rel="stylesheet" href="../dist/ng-components.css" />
    <style>
      * {
        box-sizing: border-box;
      }

      body {
        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;
        margin: 0;
        padding: 0;
        background: #f5f5f5;
      }

      .header {
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        color: white;
        padding: 30px 40px;
        box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
      }

      .header h1 {
        margin: 0 0 10px 0;
        font-size: 32px;
      }

      .header p {
        margin: 0;
        opacity: 0.9;
        font-size: 16px;
      }

      .back-link {
        display: inline-block;
        margin-top: 20px;
        padding: 10px 18px;
        background: rgba(255, 255, 255, 0.18);
        color: white;
        text-decoration: none;
        border-radius: 6px;
        transition: all 0.2s;
      }

      .back-link:hover {
        background: rgba(255, 255, 255, 0.3);
        transform: translateY(-1px);
      }

      .container {
        max-width: 1400px;
        margin: 0 auto;
        padding: 40px;
      }

      .intro-card {
        background: white;
        border-radius: 8px;
        padding: 24px 28px;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
        margin-bottom: 30px;
      }

      .intro-card h2 {
        margin: 0 0 12px 0;
        font-size: 22px;
        color: #333;
      }

      .intro-card p {
        margin: 0 0 10px 0;
        color: #4a5568;
        line-height: 1.6;
      }

      .strap-demo {
        display: flex;
        gap: 24px;
      }

      .strap-nav {
        flex: 0 0 240px;
      }

      .strap-nav .nav {
        position: relative;
      }

      .strap-nav .nav > li > a {
        padding: 10px 14px;
        border-radius: 6px;
        color: #4a5568;
        transition: all 0.2s ease;
      }

      .strap-nav .nav > li.active > a,
      .strap-nav .nav > li > a:hover {
        background: #667eea;
        color: #fff;
      }

      .strap-content {
        flex: 1;
        min-width: 0;
      }

      .demo-section {
        background: white;
        padding: 30px;
        border-radius: 8px;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
      }

      .strap-section + .strap-section {
        margin-top: 30px;
      }

      .demo-section h2 {
        margin: 0 0 20px 0;
        color: #333;
        font-size: 20px;
        border-bottom: 2px solid #667eea;
        padding-bottom: 10px;
      }

      .demo-section p {
        color: #4a5568;
        line-height: 1.6;
      }

      .strap-example {
        background: #f9fafc;
        border: 1px solid #e2e8f0;
        padding: 16px;
        border-radius: 6px;
        margin-bottom: 15px;
      }

      .strap-example .btn {
        margin-right: 10px;
        margin-bottom: 10px;
      }

      .strap-inline {
        display: flex;
        flex-wrap: wrap;
        gap: 20px;
        align-items: center;
      }

      .strap-form-control {
        max-width: 260px;
      }

      .code-block {
        background: #f7fafc;
        border: 1px solid #e2e8f0;
        border-radius: 4px;
        padding: 15px;
        margin: 10px 0 0 0;
        font-family: "Monaco", "Menlo", "Ubuntu Mono", monospace;
        font-size: 12px;
        overflow-x: auto;
      }

      .code-block code {
        color: #2d3748;
      }

      .feature-list {
        background: #f7fafc;
        border-left: 4px solid #667eea;
        padding: 15px 20px;
        margin: 20px 0;
      }

      .feature-list ul {
        margin: 0;
        padding-left: 20px;
      }

      .feature-list li {
        color: #4a5568;
        margin: 8px 0;
        line-height: 1.6;
      }

      @media (max-width: 992px) {
        .strap-demo {
          flex-direction: column;
        }

        .strap-nav {
          flex: none;
        }

        .strap-nav .nav {
          display: flex;
          overflow-x: auto;
          gap: 10px;
        }

        .strap-nav .nav > li > a {
          white-space: nowrap;
        }
      }
    </style>
  </head>
  <body ng-controller="StrapDemoController">
    <div class="header">
      <h1>Angular-Strap 组件演示</h1>
      <p>涵盖 Alert、Modal、Dropdown、Select、Datepicker、Typeahead 等指令的完整示例</p>
      <a class="back-link" href="home.html">返回主页</a>
    </div>

    <div class="container">
      <div class="intro-card">
        <h2>快速了解 Angular-Strap</h2>
        <p>
          Angular-Strap 为 AngularJS 带来了与 Bootstrap 3 风格一致的交互组件，全部以 <code>bs-*</code>
          指令形式提供，可直接与现有 HTML 结构结合使用。
        </p>
        <div class="feature-list">
          <strong>页面结构说明:</strong>
          <ul>
            <li>左侧目录启用 <code>bs-affix</code> 与 <code>bs-scrollspy-list</code>，滚动时自动吸顶并高亮对应章节</li>
            <li>右侧内容区依次演示各核心组件，包含实时数据绑定和典型配置</li>
            <li>代码块给出关键模板片段，便于复制参考</li>
          </ul>
        </div>
      </div>

      <div class="strap-demo" bs-affix-target id="strap-demo">
        <div class="strap-nav">
          <ul
            class="nav nav-pills nav-stacked strap-nav-list"
            bs-scrollspy-list
            bs-affix
            data-offset-top="140"
            data-target="#strap-content"
          >
            <li
              ng-repeat="nav in strapNavItems track by nav.id"
              ng-class="{active: activeStrapSection === nav.id}"
            >
              <a
                href="#{{ nav.id }}"
                ng-click="scrollTo(nav.id, $event)"
              >
                {{ nav.label }}
              </a>
            </li>
          </ul>
        </div>
        <div class="strap-content" id="strap-content">
          <section id="strap-overview" class="demo-section strap-section">
            <h2>Angular-Strap 组件概览</h2>
            <p>
              所有组件都建立在 Bootstrap 样式体系之上，保持一致的外观。通过引入脚本并在模块中注入
              <code>mgcrea.ngStrap</code> 后，即可在模板中直接使用各类 <code>bs-*</code> 指令。
            </p>
            <div class="feature-list">
              <strong>包含组件:</strong>
              <ul>
                <li>Alert、Aside、Modal、Dropdown、Popover、Tooltip</li>
                <li>Button 组（bs-checkbox / bs-radio）、Collapse、Tabs</li>
                <li>Select、Datepicker、Timepicker、Typeahead</li>
                <li>Navbar、Affix、Scrollspy 等导航辅助指令</li>
              </ul>
            </div>
          </section>

          <section id="strap-alert" class="demo-section strap-section">
            <h2>Alert 警告组件</h2>
            <p>注入 <code>$alert</code> 服务即可弹出带动画的提示信息，支持多种语义状态与自动关闭。</p>
            <div class="strap-example">
              <button class="btn btn-success" ng-click="openStrapAlert('success')">成功提示</button>
              <button class="btn btn-info" ng-click="openStrapAlert('info')">信息提示</button>
              <button class="btn btn-warning" ng-click="openStrapAlert('warning')">警告提示</button>
              <button class="btn btn-danger" ng-click="openStrapAlert('danger')">危险提示</button>
            </div>
            <div class="code-block">
              <code>
$alert({<br>
&nbsp;&nbsp;title: '操作成功',<br>
&nbsp;&nbsp;content: '数据已保存',<br>
&nbsp;&nbsp;type: 'success',<br>
&nbsp;&nbsp;placement: 'top',<br>
&nbsp;&nbsp;container: 'body',<br>
&nbsp;&nbsp;duration: 3,<br>
&nbsp;&nbsp;show: true<br>
});
              </code>
            </div>
          </section>

          <section id="strap-aside" class="demo-section strap-section">
            <h2>Aside 侧边抽屉</h2>
            <p><code>bs-aside</code> 指令可以从任意方向滑出抽屉面板，并支持自定义动画。</p>
            <div class="strap-example">
              <button
                class="btn btn-default"
                bs-aside
                data-placement="left"
                data-animation="am-slide-left"
                data-title="消息中心"
                data-content="在这里展示侧栏内容或者操作表单。"
              >
                从左侧打开
              </button>
              <button
                class="btn btn-default"
                bs-aside
                data-placement="right"
                data-animation="am-slide-right"
                data-title="快速设置"
                data-content="支持设置 backdrop、keyboard 等属性。"
              >
                从右侧打开
              </button>
            </div>
            <div class="code-block">
              <code>
&lt;button class="btn btn-default"<br>
&nbsp;&nbsp;bs-aside<br>
&nbsp;&nbsp;data-placement="left"<br>
&nbsp;&nbsp;data-animation="am-slide-left"<br>
&nbsp;&nbsp;data-title="消息中心"&gt;打开&lt;/button&gt;
              </code>
            </div>
          </section>

          <section id="strap-modal" class="demo-section strap-section">
            <h2>Modal 模态框</h2>
            <p><code>bs-modal</code> 支持默认模版和自定义模板两种方式，可控制遮罩、动画、键盘行为。</p>
            <div class="strap-example">
              <button
                class="btn btn-primary"
                bs-modal
                data-animation="am-fade-and-slide-top"
                data-title="审批提醒"
                data-content="这是使用默认模板渲染的模态框内容。"
              >
                标准模态框
              </button>
              <button
                class="btn btn-info"
                bs-modal
                data-template="strap/custom-modal.tpl.html"
                data-backdrop="static"
                data-animation="am-scale"
              >
                自定义模板
              </button>
            </div>
            <div class="code-block">
              <code>
&lt;button class="btn btn-primary"<br>
&nbsp;&nbsp;bs-modal<br>
&nbsp;&nbsp;data-title="审批提醒"<br>
&nbsp;&nbsp;data-content="默认模板内容"&gt;打开&lt;/button&gt;<br>
&lt;button class="btn btn-info"<br>
&nbsp;&nbsp;bs-modal<br>
&nbsp;&nbsp;data-template="strap/custom-modal.tpl.html"&gt;自定义&lt;/button&gt;
              </code>
            </div>
          </section>

          <section id="strap-dropdown" class="demo-section strap-section">
            <h2>Dropdown 下拉菜单</h2>
            <p><code>bs-dropdown</code> 能快速把按钮组变成菜单，并保持 Angular 双向绑定。</p>
            <div class="strap-example">
              <div class="btn-group" bs-dropdown>
                <button class="btn btn-default dropdown-toggle">
                  {{ strapDropdownSelected }} <span class="caret"></span>
                </button>
                <ul class="dropdown-menu" role="menu">
                  <li ng-repeat="item in strapDropdownItems">
                    <a href="" ng-click="selectDropdown(item.label)">{{ item.label }}</a>
                  </li>
                </ul>
              </div>
              <span class="text-muted">当前选择：{{ strapDropdownSelected }}</span>
            </div>
            <div class="code-block">
              <code>
&lt;div class="btn-group" bs-dropdown&gt;<br>
&nbsp;&nbsp;&lt;button class="btn btn-default dropdown-toggle"&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&#123;&#123;selected&#125;&#125; &lt;span class="caret"&gt;&lt;/span&gt;<br>
&nbsp;&nbsp;&lt;/button&gt;<br>
&nbsp;&nbsp;&lt;ul class="dropdown-menu"&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&lt;li ng-repeat="item in items"&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;a href="" ng-click="select(item)"&gt;...&lt;/a&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/li&gt;<br>
&nbsp;&nbsp;&lt;/ul&gt;<br>
&lt;/div&gt;
              </code>
            </div>
          </section>

          <section id="strap-popover" class="demo-section strap-section">
            <h2>Popover 气泡卡片</h2>
            <p>通过 <code>bs-popover</code> 可在聚焦或点击时展示提示卡片，支持 HTML 内容。</p>
            <div class="strap-example">
              <button
                class="btn btn-warning"
                bs-popover
                data-title="升级提示"
                data-content="&lt;p&gt;支持 &lt;strong&gt;HTML&lt;/strong&gt; 内容与自定义模板。&lt;/p&gt;"
                data-html="true"
                data-placement="right"
              >
                悬浮查看 Popover
              </button>
            </div>
            <div class="code-block">
              <code>
&lt;button class="btn btn-warning"<br>
&nbsp;&nbsp;bs-popover<br>
&nbsp;&nbsp;data-title="提示"<br>
&nbsp;&nbsp;data-content="&amp;lt;p&amp;gt;HTML 内容&amp;lt;/p&amp;gt;"<br>
&nbsp;&nbsp;data-html="true"&gt;Popover&lt;/button&gt;
              </code>
            </div>
          </section>

          <section id="strap-tooltip" class="demo-section strap-section">
            <h2>Tooltip 提示</h2>
            <p><code>bs-tooltip</code> 提供轻量提示气泡，可配置触发方式、延迟与方向。</p>
            <div class="strap-example strap-inline">
              <button class="btn btn-default" bs-tooltip data-title="默认提示">默认</button>
              <button class="btn btn-default" bs-tooltip data-title="延迟 1s 出现" data-delay="1000">延迟触发</button>
              <button class="btn btn-default" bs-tooltip data-title="顶部提示" data-placement="top">顶部</button>
              <button class="btn btn-default" bs-tooltip data-title="左侧提示" data-placement="left">左侧</button>
            </div>
            <div class="code-block">
              <code>
&lt;button class="btn btn-default"<br>
&nbsp;&nbsp;bs-tooltip<br>
&nbsp;&nbsp;data-placement="left"<br>
&nbsp;&nbsp;data-delay="500"<br>
&nbsp;&nbsp;data-title="提示内容"&gt;Tooltip&lt;/button&gt;
              </code>
            </div>
          </section>

          <section id="strap-button" class="demo-section strap-section">
            <h2>Button 组切换</h2>
            <p><code>bs-checkbox</code> 与 <code>bs-radio</code> 让按钮充当复选/单选，保持 Bootstrap 风格。</p>
            <div class="strap-example">
              <label>复选组：</label>
              <div class="btn-group" bs-checkbox-group ng-model="strapCheckboxes">
                <label class="btn btn-default" bs-checkbox ng-model="strapCheckboxes.analytics">分析</label>
                <label class="btn btn-default" bs-checkbox ng-model="strapCheckboxes.reports">报表</label>
                <label class="btn btn-default" bs-checkbox ng-model="strapCheckboxes.notify">通知</label>
              </div>
              <p class="text-muted">选中值：{{ strapCheckboxes | json }}</p>
              <label>单选组：</label>
              <div class="btn-group" bs-radio-group>
                <label class="btn btn-default" bs-radio ng-model="strapRadioValue" value="daily">日报</label>
                <label class="btn btn-default" bs-radio ng-model="strapRadioValue" value="weekly">周报</label>
                <label class="btn btn-default" bs-radio ng-model="strapRadioValue" value="monthly">月报</label>
              </div>
              <p class="text-muted">当前选择：{{ strapRadioValue }}</p>
            </div>
            <div class="code-block">
              <code>
&lt;div class="btn-group" bs-checkbox-group ng-model="checkboxes"&gt;<br>
&nbsp;&nbsp;&lt;label class="btn btn-default" bs-checkbox ng-model="checkboxes.a"&gt;A&lt;/label&gt;<br>
&lt;/div&gt;
              </code>
            </div>
          </section>

          <section id="strap-collapse" class="demo-section strap-section">
            <h2>Collapse 折叠面板</h2>
            <p><code>bs-collapse</code> 构建手风琴效果，支持单开、多开以及动画配置。</p>
            <div class="strap-example">
              <div class="panel-group" bs-collapse ng-model="strapCollapse.active">
                <div class="panel panel-default" ng-repeat="item in strapCollapse.sections track by $index">
                  <div class="panel-heading">
                    <h4 class="panel-title">
                      <a href="" bs-collapse-toggle="{{$index}}">
                        {{ item.title }}
                      </a>
                    </h4>
                  </div>
                  <div class="panel-collapse collapse" bs-collapse-target>
                    <div class="panel-body">
                      {{ item.content }}
                    </div>
                  </div>
                </div>
              </div>
            </div>
            <div class="code-block">
              <code>
&lt;div class="panel-group" bs-collapse ng-model="active"&gt;<br>
&nbsp;&nbsp;&lt;div class="panel panel-default" ng-repeat="section in sections"&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&lt;a href="" bs-collapse-toggle="&#123;&#123;$index&#125;&#125;"&gt;...&lt;/a&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&lt;div class="panel-collapse collapse" bs-collapse-target&gt;...&lt;/div&gt;<br>
&nbsp;&nbsp;&lt;/div&gt;<br>
&lt;/div&gt;
              </code>
            </div>
          </section>

          <section id="strap-tabs" class="demo-section strap-section">
            <h2>Tabs 标签页</h2>
            <p><code>bs-tabs</code> 与 <code>bs-pane</code> 组合，可以通过 <code>bs-active-pane</code> 控制激活项。</p>
            <div class="strap-example">
              <div bs-tabs bs-active-pane="strapTabs.active">
                <div bs-pane title="运行概况">
                  <p>系统运行时间：{{ strapTabs.stats.uptime }}</p>
                </div>
                <div bs-pane title="任务队列">
                  <p>排队任务：{{ strapTabs.stats.queue }}</p>
                </div>
                <div bs-pane title="错误日志">
                  <p>近 24 小时错误：{{ strapTabs.stats.errors }}</p>
                </div>
              </div>
            </div>
            <div class="code-block">
              <code>
&lt;div bs-tabs bs-active-pane="activeTab"&gt;<br>
&nbsp;&nbsp;&lt;div bs-pane title="概览"&gt;内容&lt;/div&gt;<br>
&nbsp;&nbsp;&lt;div bs-pane title="日志"&gt;内容&lt;/div&gt;<br>
&lt;/div&gt;
              </code>
            </div>
          </section>

          <section id="strap-select" class="demo-section strap-section">
            <h2>Select 选择器</h2>
            <p><code>bs-select</code> 让按钮/输入框具备搜索与多选能力，语法与 <code>ng-options</code> 类似。</p>
            <div class="strap-example">
              <div class="strap-inline">
                <button
                  type="button"
                  class="btn btn-default"
                  ng-model="strapSelect.single"
                  bs-select
                  data-placeholder="选择地区"
                  bs-options="region.value as region.label group by region.group for region in strapSelect.options"
                >
                  单选：{{ strapSelect.single || '未选择' }}
                </button>
                <button
                  type="button"
                  class="btn btn-default"
                  ng-model="strapSelect.multiple"
                  bs-select
                  data-multiple="1"
                  data-placeholder="选择标签"
                  bs-options="tag.value as tag.label for tag in strapSelect.tags"
                >
                  多选：{{ (strapSelect.multiple && strapSelect.multiple.length > 0) ? strapSelect.multiple.join(', ') : '未选择' }}
                </button>
              </div>
            </div>
            <div class="code-block">
              <code>
&lt;button class="btn btn-default" ng-model="selected" bs-select<br>
&nbsp;&nbsp;bs-options="item.value as item.label for item in items"&gt;<br>
&nbsp;&nbsp;&#123;&#123;selected || '请选择'&#125;&#125;<br>
&lt;/button&gt;
              </code>
            </div>
          </section>

          <section id="strap-datepicker" class="demo-section strap-section">
            <h2>Datepicker / Timepicker</h2>
            <p>日期与时间选择器遵循 Bootstrap 外观，可配置格式、步长和自动关闭。</p>
            <div class="strap-example strap-inline">
              <div>
                <label>日期：</label>
                <input
                  type="text"
                  class="form-control strap-form-control"
                  ng-model="strapDate"
                  bs-datepicker
                  data-date-format="yyyy-MM-dd"
                  data-autoclose="1"
                />
              </div>
              <div>
                <label>时间：</label>
                <input
                  type="text"
                  class="form-control strap-form-control"
                  ng-model="strapTime"
                  bs-timepicker
                  data-minute-step="5"
                  data-show-seconds="false"
                />
              </div>
              <div>
                <p class="text-muted">当前值：{{ strapDate | date:'yyyy-MM-dd' }} {{ strapTime | date:'HH:mm' }}</p>
              </div>
            </div>
            <div class="code-block">
              <code>
&lt;input type="text" ng-model="pickedDate" bs-datepicker data-autoclose="1"&gt;<br>
&lt;input type="text" ng-model="pickedTime" bs-timepicker data-minute-step="5"&gt;
              </code>
            </div>
          </section>

          <section id="strap-typeahead" class="demo-section strap-section">
            <h2>Typeahead 自动补全</h2>
            <p><code>bs-typeahead</code> 使用 <code>bs-options</code> 语法提供关键字联想。</p>
            <div class="strap-example strap-inline">
              <input
                type="text"
                class="form-control strap-form-control"
                placeholder="输入州名称"
                ng-model="strapTypeaheadValue"
                bs-typeahead
                bs-options="state for state in strapTypeaheadStates"
                data-min-length="1"
              />
              <p class="text-muted">选中值：{{ strapTypeaheadValue }}</p>
            </div>
            <div class="code-block">
              <code>
&lt;input type="text" ng-model="keyword" bs-typeahead<br>
&nbsp;&nbsp;bs-options="option for option in options" data-min-length="1"&gt;
              </code>
            </div>
          </section>

          <section id="strap-navbar" class="demo-section strap-section">
            <h2>Navbar 导航条</h2>
            <p><code>bs-navbar</code> 根据 <code>$location.path()</code> 自动高亮匹配路由，可结合自定义逻辑。</p>
            <div class="strap-example">
              <nav class="navbar navbar-default" bs-navbar>
                <div class="container-fluid">
                  <ul class="nav navbar-nav">
                    <li data-match-route="/dashboard">
                      <a href="" ng-click="setStrapRoute('/dashboard')">仪表盘</a>
                    </li>
                    <li data-match-route="/projects">
                      <a href="" ng-click="setStrapRoute('/projects')">项目</a>
                    </li>
                    <li data-match-route="/reports">
                      <a href="" ng-click="setStrapRoute('/reports')">报表</a>
                    </li>
                  </ul>
                </div>
              </nav>
              <p class="text-muted">当前路径：{{ strapCurrentRoute }}</p>
            </div>
            <div class="code-block">
              <code>
&lt;nav class="navbar navbar-default" bs-navbar&gt;<br>
&nbsp;&nbsp;&lt;ul class="nav navbar-nav"&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&lt;li data-match-route="/dashboard"&gt;...&lt;/li&gt;<br>
&nbsp;&nbsp;&lt;/ul&gt;<br>
&lt;/nav&gt;
              </code>
            </div>
          </section>

          <section id="strap-affix" class="demo-section strap-section">
            <h2>Affix &amp; Scrollspy</h2>
            <p>左侧目录演示了 <code>bs-affix</code> 与 <code>bs-scrollspy-list</code> 的组合用法。</p>
            <div class="strap-example">
              <pre style="margin:0;"><code>
&lt;div class="strap-nav"&gt;
&nbsp;&nbsp;&lt;ul class="nav nav-pills"
&nbsp;&nbsp;&nbsp;&nbsp;bs-scrollspy-list
&nbsp;&nbsp;&nbsp;&nbsp;bs-affix
&nbsp;&nbsp;&nbsp;&nbsp;data-offset-top="140"
&nbsp;&nbsp;&nbsp;&nbsp;data-target="#strap-content"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;li&gt;&lt;a href="#strap-alert"&gt;Alert&lt;/a&gt;&lt;/li&gt;
&nbsp;&nbsp;&nbsp;&nbsp;...
&nbsp;&nbsp;&lt;/ul&gt;
&lt;/div&gt;
              </code></pre>
            </div>
            <p class="text-muted">滚动页面时观察目录吸顶效果与锚点高亮。</p>
          </section>
        </div>
      </div>
    </div>

    <script type="text/ng-template" id="strap/custom-modal.tpl.html">
      <div class="modal" tabindex="-1" role="dialog" aria-hidden="true">
        <div class="modal-dialog modal-md">
          <div class="modal-content">
            <div class="modal-header">
              <button type="button" class="close" aria-label="Close" ng-click="$hide()">
                <span aria-hidden="true">&times;</span>
              </button>
              <h4 class="modal-title">发布公告</h4>
            </div>
            <div class="modal-body">
              <p>可以在自定义模板内放置表单、列表或任何内容。</p>
              <ul class="list-unstyled">
                <li><span class="glyphicon glyphicon-send"></span> 支持调用 <code>$hide()</code> / <code>$dismiss()</code> 控制弹窗。</li>
                <li><span class="glyphicon glyphicon-time"></span> 结合 <code>backdrop="static"</code> 可阻止外部区域关闭。</li>
              </ul>
            </div>
            <div class="modal-footer">
              <button type="button" class="btn btn-default" ng-click="$hide()">稍后</button>
              <button type="button" class="btn btn-primary" ng-click="$hide()">立即发布</button>
            </div>
          </div>
        </div>
      </div>
    </script>

    <script src="https://cdn.jsdelivr.net/npm/angular@1.8.3/angular.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/angular-strap@2.3.12/dist/angular-strap.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/angular-strap@2.3.12/dist/angular-strap.tpl.min.js"></script>
    <script>
      angular
        .module("strapDemoApp", ["mgcrea.ngStrap"])
        .config(["$locationProvider", function($locationProvider) {
          $locationProvider.hashPrefix("");
        }])
        .controller("StrapDemoController", ["$scope", "$alert", "$location", "$window", "$document", "$timeout", function($scope, $alert, $location, $window, $document, $timeout) {
          $scope.strapDropdownItems = [
            { label: "新建任务" },
            { label: "发布公告" },
            { label: "导出报表" },
            { label: "归档" }
          ];

          $scope.strapDropdownSelected = "选择操作";
          $scope.selectDropdown = function(label) {
            $scope.strapDropdownSelected = label;
          };

          $scope.strapCheckboxes = {
            analytics: true,
            reports: false,
            notify: true
          };

          $scope.strapRadioValue = "monthly";

          $scope.strapCollapse = {
            active: 0,
            sections: [
              {
                title: "性能监控",
                content: "展示系统 CPU、内存、响应时间等实时性能指标。"
              },
              {
                title: "队列任务",
                content: "列出待处理任务，支持快速重试和取消操作。"
              },
              {
                title: "安全提醒",
                content: "聚合登录异常、风控报警等安全相关事件。"
              }
            ]
          };

          $scope.strapTabs = {
            active: 0,
            stats: {
              uptime: "132 小时",
              queue: 5,
              errors: 2
            }
          };

          $scope.strapSelect = {
            single: null,
            multiple: [],
            options: [
              { group: "华北", label: "北京", value: "beijing" },
              { group: "华北", label: "天津", value: "tianjin" },
              { group: "华东", label: "上海", value: "shanghai" },
              { group: "华东", label: "杭州", value: "hangzhou" },
              { group: "华南", label: "广州", value: "guangzhou" },
              { group: "华南", label: "深圳", value: "shenzhen" }
            ],
            tags: [
              { label: "紧急", value: "urgent" },
              { label: "待审核", value: "pending" },
              { label: "归档", value: "archived" }
            ]
          };

          $scope.strapDate = new Date();
          $scope.strapTime = new Date();

          $scope.strapTypeaheadStates = [
            "Alabama",
            "Alaska",
            "Arizona",
            "Arkansas",
            "California",
            "Colorado",
            "Florida",
            "Georgia",
            "Hawaii",
            "Idaho",
            "Illinois",
            "Indiana",
            "Kansas",
            "Kentucky",
            "Louisiana",
            "Maine",
            "Maryland",
            "Massachusetts",
            "Michigan",
            "Minnesota",
            "Mississippi",
            "Missouri",
            "Montana",
            "Nebraska",
            "Nevada",
            "New Hampshire",
            "New Jersey",
            "New Mexico",
            "New York",
            "North Carolina",
            "Ohio",
            "Oklahoma",
            "Oregon",
            "Pennsylvania",
            "Rhode Island",
            "South Carolina",
            "South Dakota",
            "Tennessee",
            "Texas",
            "Utah",
            "Vermont",
            "Virginia",
            "Washington",
            "West Virginia",
            "Wisconsin",
            "Wyoming"
          ];

          $scope.strapTypeaheadValue = "";

          var strapAlertCopy = {
            success: {
              title: "操作成功",
              content: "数据已保存，可以继续下一步。"
            },
            info: {
              title: "提示信息",
              content: "这是一个普通的信息通知。"
            },
            warning: {
              title: "注意风险",
              content: "请确认输入信息是否正确。"
            },
            danger: {
              title: "操作失败",
              content: "服务器暂时不可用，请稍后重试。"
            }
          };

          $scope.strapNavItems = [
            { id: "strap-overview", label: "概览" },
            { id: "strap-alert", label: "Alert" },
            { id: "strap-aside", label: "Aside" },
            { id: "strap-modal", label: "Modal" },
            { id: "strap-dropdown", label: "Dropdown" },
            { id: "strap-popover", label: "Popover" },
            { id: "strap-tooltip", label: "Tooltip" },
            { id: "strap-button", label: "Button" },
            { id: "strap-collapse", label: "Collapse" },
            { id: "strap-tabs", label: "Tabs" },
            { id: "strap-select", label: "Select" },
            { id: "strap-datepicker", label: "Date/Time" },
            { id: "strap-typeahead", label: "Typeahead" },
            { id: "strap-navbar", label: "Navbar" },
            { id: "strap-affix", label: "Affix & Scrollspy" }
          ];

          var strapSectionIds = $scope.strapNavItems.map(function(item) {
            return item.id;
          });

          $scope.activeStrapSection = strapSectionIds[0];

          var headerOffset = 120;
          var highlightOffset = headerOffset + 20;
          var scrollTicking = false;
          var winEl = angular.element($window);

          $scope.scrollTo = function(section, $event) {
            if ($event) {
              $event.preventDefault();
            }

            var docEl = $document[0].documentElement;
            var bodyEl = $document[0].body;
            var target = $document[0].getElementById(section);

            if (!target) {
              return;
            }

            var currentScroll = $window.pageYOffset || docEl.scrollTop || 0;
            var targetTop =
              target.getBoundingClientRect().top + currentScroll - headerOffset;

            if (targetTop < 0) {
              targetTop = 0;
            }

            if (typeof $window.scrollTo === "function") {
              try {
                $window.scrollTo({
                  top: targetTop,
                  behavior: "smooth"
                });
              } catch (err) {
                $window.scrollTo(0, targetTop);
              }
            } else {
              docEl.scrollTop = targetTop;
              if (bodyEl) {
                bodyEl.scrollTop = targetTop;
              }
            }

            $scope.activeStrapSection = section;
            $location.hash(section);

            $timeout(function() {
              updateActiveSection();
            }, 350);
          };

          function updateActiveSection() {
            var docEl = $document[0].documentElement;
            var scrollTop = ($window.pageYOffset || docEl.scrollTop || 0) + highlightOffset;
            var current = strapSectionIds[0];

            strapSectionIds.forEach(function(id) {
              var el = $document[0].getElementById(id);

              if (!el) {
                return;
              }

              if (scrollTop >= el.offsetTop) {
                current = id;
              }
            });

            if (current !== $scope.activeStrapSection) {
              $scope.$applyAsync(function() {
                $scope.activeStrapSection = current;
              });
            }
          }

          function onScroll() {
            if (scrollTicking) {
              return;
            }

            scrollTicking = true;

            if ($window.requestAnimationFrame) {
              $window.requestAnimationFrame(runScrollUpdate);
            } else {
              $timeout(runScrollUpdate, 120);
            }
          }

          function runScrollUpdate() {
            scrollTicking = false;
            updateActiveSection();
          }

          winEl.on("scroll", onScroll);

          $scope.$on("$destroy", function() {
            winEl.off("scroll", onScroll);
          });

          $timeout(updateActiveSection, 0);

          var initialHash = $location.hash();
          if (initialHash && strapSectionIds.indexOf(initialHash) !== -1) {
            $timeout(function() {
              $scope.scrollTo(initialHash);
            }, 100);
          }

          $scope.openStrapAlert = function(type) {
            var payload = strapAlertCopy[type] || strapAlertCopy.info;
            $alert(
              angular.extend(
                {
                  placement: "top",
                  container: "body",
                  duration: 3,
                  show: true,
                  type: type
                },
                payload
              )
            );
          };

          function ensureRoute(path) {
            if (!path) {
              path = "/dashboard";
            }
            $scope.strapCurrentRoute = path;
          }

          ensureRoute($location.path());

          $scope.setStrapRoute = function(path) {
            $location.path(path);
            $scope.strapCurrentRoute = path;
          };

          $scope.$watch(function() {
            return $location.path();
          }, function(newPath) {
            if (newPath) {
              $scope.strapCurrentRoute = newPath;
            }
          });
        }]);
    </script>
  </body>
</html>
